﻿using UnityEngine;
using System;
using System.Collections.Generic;
using Dict.DataModel;
using Dict.Blo;
using ProtoBuf.Message;
namespace Story
{
    public class StoryManager : MonoBehaviour
    {
        #region Instance
        private static StoryManager instance;
        public static StoryManager Instance
        {
            get
            {
                return instance;
            }
        }
        void Awake()
        {
            instance = this;
            //Room.RCAIArea.eventEnterAreaHandler += OnEnterArea;
            
            completeQuests = StaticData.storyData.completeQuestIds;
        }

        #endregion

        public StoryDialogManager dialogManager;
        public GameObject maskObject;

        public List<string> completeQuests;

        public bool ignorePreQuest=false;
        public bool autoCompleteQuest = true;

        //private bool saved = false;
        public delegate void QuestChangeHandler(string questId);
        public static QuestChangeHandler questChangeHandler;


        private Action eventEndHandler;
        private Action otherEndHandler;
        private bool running = false;

        private TableStoryQuest curQuest;
        private Queue<StepBase> curSteps = new Queue<StepBase>();

        //private bool saved = false;
        private int prelevel;
        public void OnLogin()
        {
            DataMessageTool.AddHandler(DataMessage.AREA_ENTER, OnEnterArea);
            DataMessageTool.AddHandler(DataMessage.NPC_CLICK, OnClickNPC);
        }
        public void Clear()
        {
            running = false;
            eventEndHandler = null;
            maskObject.SetActive(false);
            dialogManager.gameObject.SetActive(false);
            questChangeHandler = null;

            dialogManager.Clear();

            curSteps.Clear();
            curQuest = null;
        }
        public void SendEvent(EventType eventType, string param, Action endHandler)
        {
            bool run = false;
            if (!running && curSteps.Count > 0)
            {
                var curStep = curSteps.Peek();
                if (eventType == curStep.eventType && param.Equals(curStep.eventParam))
                {
                    run = true;
                }
            }
            if (run)
            {
                this.eventEndHandler = endHandler;
                RunStart();
            }
            else
            {
                if (endHandler != null)
                {
                    endHandler();
                }
            }
        }

        public void RunStart()
        {
            running = true;
            var step = curSteps.Dequeue();
            Debug.Log("[StoryStep]EventType:" + step.eventType.ToString() + " EventParam:" + step.eventParam +
                " ActionType:" + step.actionType.ToString() + " ActionParam1:" + step.actionParam1 +
                " ActionParam2:" + step.actionParam2 + " ActionParam3:" + step.actionParam3);
            step.Start();
        }

        public void RunEnd()
        {
            running = false;
            if (curSteps.Count == 0)
            {
                OnStepFinished();
                if (eventEndHandler != null)
                {
                    eventEndHandler();
                    eventEndHandler = null;
                }
            }
            else
            {
                if (curSteps.Peek().eventType == EventType.None)
                {
                    RunStart();
                }
                else
                {
                    if (eventEndHandler != null)
                    {
                        eventEndHandler();
                        eventEndHandler = null;
                        return;
                    }
                }
            }
        }

        void Update()
        {
            //if (running)
            //    return;

            

        }

        public void OnEnterArea(object areaCharactor)
        {
            string areaId = (areaCharactor as Room.RoomCharactor).name;
            SendEvent(EventType.EnterArea, areaId, null);
        }

        public void OnClickNPC(object npcCharactor)
        {
            string npcId = (npcCharactor as Room.RoomCharactor).name;
            SendEvent(EventType.ClickNPC, npcId, null);
        }

        public void OnStepFinished()
        {
            if (curQuest.type == (int)QuestType.Town)
            {
                prelevel = StaticData.playerData.level;
                CSQuestReward sendMsg = new CSQuestReward();
                sendMsg.questId = curQuest.questId;
                NetAPI.SendHttp(OpDefine.CSQuestReward, sendMsg,
                    (packet, bSuccess) =>
                    {
                        if (bSuccess)
                        {
                            SCQuestReward recvMsg = packet.kBody as SCQuestReward;
                            StaticData.playerData.AddResultObj(recvMsg.get);
                            StaticData.storyData.AddFinishQuest(curQuest.questId);

                            otherEndHandler = CheckLevelUp;
                            OpenQuestCompletePage(recvMsg.get, curQuest.questId);

                            curQuest = null;
                            curSteps.Clear();

                            questChangeHandler(StaticData.storyData.GetCurQuestId());

                            //看看有没有新的主城任务
                            OnTownPageOpen();
                        }
                    });

            } else if (curQuest.type == (int)QuestType.Copy)
            {

            }
        }

        /// <summary>
        /// 主城类任务 进入主城时开始
        /// </summary>
        public void OnTownPageOpen()
        {
            //取到最新的任务

            TableStoryQuest nextQuest = DictStoryBlo.GetQuest(StaticData.storyData.GetCurQuestId());

            questChangeHandler(nextQuest.questId);

            //新的任务是否主城类
            if (nextQuest.type != (int)QuestType.Town)
                return;
            //开始任务
            curQuest = nextQuest;
            var stepDatas = DictStoryBlo.GetStoryOfQuest(curQuest.questId);

            foreach (var stepData in stepDatas)
            {
                StepBase step = CreateStep(stepData);
                curSteps.Enqueue(step);
            }
            SendEvent(EventType.EnterTown, "", null);
        }
        /// <summary>
        /// 主城类任务 关闭主城时清空
        /// </summary>
        public void OnTownPageClose()
        {
            curQuest = null;
            curSteps.Clear();
        }


        /// <summary>
        /// 副本类任务 点击副本挑战时开始
        /// </summary>
        /// <param name="missionId"></param>
        /// <param name="endHandler"></param>
        public void OnCopyChallenge(string missionId, Action endHandler)
        {
            //开始副本类任务
            curSteps.Clear();
            curQuest = null;

            var questData = DictStoryBlo.GetQuestOfMission(missionId);
            if (questData == null || questData.type != (int)QuestType.Copy||StaticData.storyData.isQuestFinished(questData.questId))
            {
                endHandler();
                return;
            }
            curQuest = questData;
            var stepDatas = DictStoryBlo.GetStoryOfQuest(curQuest.questId);

            foreach (var stepData in stepDatas)
            {
                StepBase step = CreateStep(stepData);
                curSteps.Enqueue(step);
            }

            SendEvent(EventType.BeforeEnterCopy, missionId, endHandler);
        }
        /// <summary>
        /// 副本类任务 回到副本界面后结束
        /// </summary>
        public void OnCopyPageOpen(Action endHandler)
        {
            maskObject.SetActive(false);

            //有没有执行中的副本任务
            if (curQuest == null)
            {
                if(autoCompleteQuest)
                    _OnCopyPageOpen(endHandler);
                return;
            }
            
            //副本任务是否完成
            SendEvent(EventType.EnterTown, "", () =>
              {
                  if (StaticData.storyData.isQuestFinished(curQuest.questId))
                  {
                      OpenQuestCompletePage(StaticData.storyTmpQuestGet, curQuest.questId);
                      StaticData.storyTmpQuestGet = null;

                      questChangeHandler(StaticData.storyData.GetCurQuestId());

                      curSteps.Clear();
                      curQuest = null;
                      this.otherEndHandler = endHandler;
                  }
                  else
                  {
                      curSteps.Clear();
                      curQuest = null;
                      if (autoCompleteQuest)
                          _OnCopyPageOpen(endHandler);
                  }
              });
        }
        public void _OnCopyPageOpen(Action endHandler)
        {
            foreach (var chapter in StaticData.copyData.copy_chapters)
            {
                foreach (var level in chapter.chapter_levels)
                {
                    if(level.level_inst_star>0)
                    {
                        var quest = DictStoryBlo.GetQuestOfMission(level.level_id);
                        if(quest == null)
                        {
                            Debug.LogError("Quest story no data of mission id " + level.level_id);
                            continue;
                        }
                        if(!StaticData.storyData.isQuestFinished(quest.questId))
                        {
                            CSQuestReward sendMsg = new CSQuestReward();
                            sendMsg.questId = quest.questId;
                            NetAPI.SendHttp(OpDefine.CSQuestReward, sendMsg,
                                (packet, bSuccess) =>
                                {
                                    if (bSuccess)
                                    {
                                        SCQuestReward recvMsg = packet.kBody as SCQuestReward;
                                        StaticData.playerData.AddResultObj(recvMsg.get);
                                        StaticData.storyData.AddFinishQuest(quest.questId);
                                    }
                                });
                            if (endHandler != null)
                            {
                                endHandler();
                            }
                            return;
                        }
                    }
                }
            }

            if (endHandler != null)
            {
                endHandler();
            }
        }

        public void OnQuestCompletePageClose()
        {
            if(otherEndHandler!=null)
            {
                otherEndHandler();
                otherEndHandler = null;
            }
        }

        public void CheckLevelUp()
        {
            if(prelevel!=0&&StaticData.playerData.level!=prelevel)
            {
                BoxManager.CreateLevelUp(prelevel, StaticData.playerData.level);
                prelevel = 0;
            }
        }
        //副本章节过关时
        public void OnMissionComplete(string missionId,Action handler)
        {
            var quest = DictStoryBlo.GetQuestOfMission(missionId);
            if(quest==null)
            {
                if(handler!=null)
                {
                    handler();
                }
                return;
            }
            if(!StaticData.storyData.isQuestFinished(quest.questId))
            {
                CSQuestReward sendMsg = new CSQuestReward();
                sendMsg.questId = quest.questId;
                NetAPI.SendHttp(OpDefine.CSQuestReward, sendMsg,
                    (packet, bSuccess) =>
                    {
                        if (bSuccess)
                        {
                            SCQuestReward recvMsg = packet.kBody as SCQuestReward;
                            StaticData.playerData.AddResultObj(recvMsg.get);
                            StaticData.storyTmpQuestGet = recvMsg.get;
                            StaticData.storyData.AddFinishQuest(quest.questId);

                        }
                        if (handler != null)
                        {
                            handler();
                        }
                    });
            }
            else
            {
                if (handler != null)
                {
                    handler();
                }
            }

            
        }

        
        private void OpenQuestCompletePage(ResultObject get,string questId)
        {
            string option = "questId="+questId;
            if (get != null)
            {
                StaticData.playerData.AddResultObj(get);

                foreach (var tmp in get.simps)
                    option += "&" + tmp.id + "=" + tmp.num;
                foreach (var tmp in get.wars)
                    option += "&" + tmp.id + "=" + 1;
                foreach (var tmp in get.equips)
                    option += "&" + tmp.equipId + "=" + 1;
                foreach (var tmp in get.treas)
                    option += "&" + tmp.treasureId + "=" + 1;
            }
            UI.PageManager.instance.OpenPage("QuestCompletePage", option);
        }
        private StepBase CreateStep(TableStory stepData)
        {
            
            StepBase step = null;
            switch ((ActionType)stepData.actionType)
            {
                case ActionType.Tip:
                    step = new StepTip();
                    break;
                case ActionType.Delay:
                    step = new StepDelay();
                    break;
                case ActionType.Dialog2D:
                    step = new StepDialog();
                    break;
                case ActionType.Bubble:
                    step = new StepBubble();
                    break;
                case ActionType.CreateNPC:
                    step = new StepCreateNPC();
                    break;
                case ActionType.MoveCamera:
                    step = new StepMoveCamera();
                    break;
                case ActionType.DestroyCharactor:
                    step = new StepDestroyCharactor();
                    break;
                case ActionType.MoveCharactor:
                    step = new StepMoveCharactor();
                    break;
                case ActionType.PlayCharactorAnim:
                    step = new StepPlayCharactorAnim();
                    break;
                case ActionType.RotateCharactor:
                    step = new StepRotateCharactor();
                    break;
                case ActionType.StayCopy:
                    step = new StepStayCopy();
                    break;
                case ActionType.LeaveCopy:
                    step = new StepLeaveCopy();
                    break;
                case ActionType.ForbidControl:
                    step = new StepForbidControl();
                    break;
                case ActionType.PermitControl:
                    step = new StepPermitControl();
                    break;
                case ActionType.PositionCharactor:
                    step = new StepPositionCharactor();
                    break;
                case ActionType.StartCopyBattle:
                    step = new StepStartCopyBattle();
                    break;
                case ActionType.PlayParticle:
                    step = new StepPlayParticle();
                    break;
                default:
                    step = new StepBase();
                    break;
            }
            step.Init(this, stepData);
            return step;
        }

        public bool isRunning()
        {
            return running;
        }

        public TableStoryQuest GetCurQuest()
        {
            return curQuest;
        }
    }
}


